package com.atguigu.yygh.cmn.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.util.StringUtils;
import com.atguigu.yygh.cmn.listener.DictListener;
import com.atguigu.yygh.cmn.mapper.CmnMapper;
import com.atguigu.yygh.cmn.service.CmnService;
import com.atguigu.yygh.model.cmn.Dict;
import com.atguigu.yygh.vo.cmn.DictEeVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 * @author ybl
 * @version 1.9
 * @date 2021/5/14 14:49
 */
@Service
public class CmnServiceImpl extends ServiceImpl<CmnMapper, Dict> implements CmnService {

  // 导入数据
  // 参数一: 命名空间  参数二: 是否删除所有缓存
  @CacheEvict(value = "dict",allEntries = true)
  @Override
  public void importDictData(MultipartFile file) {
    try {
      EasyExcel.read(file.getInputStream(),DictEeVo.class,new DictListener(baseMapper)).sheet().doRead();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  // 根据dictCode和value查询字典名称
  @Override
  public String getNameByParentDictCodeAndValue(String dictCode, String value) {
    // 如果dictcode为空,直接根据value查询
    if (StringUtils.isEmpty(dictCode)){
      Dict dict = baseMapper.selectOne(new QueryWrapper<Dict>().eq("value", value));
      return dict.getName();
    }else {// 如果dictcode不为空,根据dictcode 和 value查询
      Dict dict = baseMapper.selectOne(new QueryWrapper<Dict>().eq("dict_code", dictCode));
      Long dictId = dict.getId();
      Dict dictAndValue = baseMapper.selectOne(new QueryWrapper<Dict>().eq("parent_id", dictId).eq("value", value));
      return dictAndValue.getName();
    }
  }

  // 根据dictCode获取下级节点
  @Override
  public List<Dict> findByDictCode(String dictCode) {
    // 根据dict_code查出 字典父目录的id
    Dict dict = baseMapper.selectOne(new QueryWrapper<Dict>().eq("dict_code", dictCode));
    return findChlidData(dict.getId());
  }

  // 导出数据
  @Override
  public void exportDictData(HttpServletResponse response) {

    // 防止中文乱码
    String fileName = null;
    try {
      fileName = URLEncoder.encode("数据字典","utf-8");
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }

    response.setContentType("application/vnd.ms-excel");
    response.setCharacterEncoding("UTF-8");
    // 以下载形式打开 用户可自选文件夹
    response.setHeader("Content-disposition","attachment;filename="+fileName+".xlsx");

    List<Dict> dicts = baseMapper.selectList(null);
    List<DictEeVo> dictEeVos = new ArrayList<>();
    for (Dict dict : dicts) {
      DictEeVo dictEeVo = new DictEeVo();
      BeanUtils.copyProperties(dict,dictEeVo,DictEeVo.class);
      dictEeVos.add(dictEeVo);
    }
    ServletOutputStream outputStream = null;
    try {
      outputStream =  response.getOutputStream();
      EasyExcel.write(outputStream, DictEeVo.class).sheet("数据字典")
          .doWrite(dictEeVos);
    } catch (IOException e) {
      e.printStackTrace();
    }finally {
      try {
        outputStream.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }

  }


  // 查找 id 的子节点
  // 参数一: 命名空间    参数二: 自定义kdy的命名规则
  @Cacheable(value = "dict",keyGenerator = "keyGenerator")
  @Override
  public List<Dict> findChlidData(Long id) {

    QueryWrapper<Dict> wrapper = new QueryWrapper<>();
    wrapper.eq("parent_id",id);
    List<Dict> dicts = baseMapper.selectList(wrapper);
    for (Dict dict : dicts) {
      // 是否有子节点
      boolean hasChildren = hasChildren(dict.getId());
      dict.setHasChildren(hasChildren);
    }

    return dicts;
  }

  // 判断id下是否还有子节点
  private boolean hasChildren(Long id){
    QueryWrapper<Dict> wrapper = new QueryWrapper<>();
    wrapper.eq("parent_id",id);
    Integer count = baseMapper.selectCount(wrapper); // 父节点为 id 的是否有数据
    return count > 0;
  }
}
